package homework;
import java.time.LocalDate;                  // 日期类
import java.time.format.DateTimeFormatter;  // 日期格式化/解析
import java.time.format.DateTimeParseException; // 日期解析异常
import java.time.DayOfWeek;                  // 星期枚举
import java.time.temporal.ChronoUnit;       // 计算时间间隔
import java.util.Scanner;                    // 输入

public class 实验6 {
    // 日期格式化器 - 用于将字符串转换为LocalDate
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    //常量化一个工具类
    private static final Scanner SCANNER = new Scanner(System.in);
    public static void main(String[] args) {
        while (true) {
            System.out.println("\n请选择操作：");
            System.out.println("1 - 输入日期，计算星期几");
            System.out.println("2 - 输入日期和天数，计算日期+天数");
            System.out.println("3 - 输入日期和天数或日期，计算日期减天数或日期差");
            System.out.println("0 - 退出");
            String choice = SCANNER.nextLine().trim();   // 读取操作选择 ——【输入读取】
            switch (choice) {
                case "1": calculateDayOfWeek(); break;
                case "2": datePlusDays(); break;
                case "3": flexibleDateCalculation(); break;
                case "0":
                    System.out.println("退出程序。");
                    //结束main方法,直接return
                    return;
                default:
                    System.out.println("无效指令，请重新选择。");
            }
        }
    }


    // 读取日期，并验证合法性
    private static LocalDate inputDate(String prompt) {
        while (true) {
            System.out.print(prompt);
            String input = SCANNER.nextLine().trim();    // 读取一行输入

            try {
                // 将字符串解析为LocalDate，根据指定格式
                LocalDate date = LocalDate.parse(input, FORMATTER);
                return date;
            } catch (DateTimeParseException e) {
                // 输入格式不正确或者非法日期时捕获异常
                System.out.println("输入的日期格式或者日期不合法，格式应为 yyyy-MM-dd, 请重新输入。");
            }
        }
    }

    // 读取非负天数的整数
    private static int inputDays(String prompt) {
        while (true) {
            System.out.print(prompt);
            String input = SCANNER.nextLine().trim();

            try {
                int days = Integer.parseInt(input);  // 字符串转整数
                // 非负校验
                if (days < 0) {
                    System.out.println("请输入非负的天数。");
                    continue;
                }
                return days;
            } catch (NumberFormatException e) {
                // 非法数字格式异常处理
                System.out.println("输入的天数不合法，请输入整数。");
            }
        }
    }

    // 读取日期或天数（字符串），判定返回 LocalDate 或 Integer
    private static Object inputDateOrDays(String prompt) {
        while (true) {
            System.out.print(prompt);
            String input = SCANNER.nextLine().trim();

            // 尝试解析日期
            try {
                LocalDate date = LocalDate.parse(input, FORMATTER);
                return date;
            } catch (DateTimeParseException ignored) {}

            // 尝试解析整数天数
            try {
                int days = Integer.parseInt(input);
                if (days < 0) {
                    System.out.println("请输入非负的天数或者有效的日期。");
                    continue;
                }
                return days;
            } catch (NumberFormatException e) {
                System.out.println("请输入合法的日期（yyyy-MM-dd）或者非负整数天数。");
            }
        }
    }

    // 计算日期对应的星期几，输出星期值（1=Monday，7=Sunday）
    private static void calculateDayOfWeek() {
        System.out.println("==== 计算日期对应星期几 ====");
        LocalDate date = inputDate("请输入日期(格式 yyyy-MM-dd)：");
    //枚举里面的元素其实是一个对象
        DayOfWeek dayOfWeek = date.getDayOfWeek();  // 获取星期枚举
        // dayOfWeek.getValue() 返回 1~7 代表星期一到星期日
        //%s，占位符的使用，python，c都有这样的用法
        System.out.printf("日期 %s 是星期%s", date, dayOfWeek);
    }

    // 日期加指定天数计算
    private static void datePlusDays() {
        System.out.println("==== 日期加天数计算 ====");
        LocalDate date = inputDate("请输入日期(格式 yyyy-MM-dd)：");
        int days = inputDays("请输入要加的天数(非负整数)：");
        //我们主要使用的都是这个data中的方法
        LocalDate newDate = date.plusDays(days);    // 增加天数，返回新日期
        System.out.printf("%s 加 %d 天后是 %s\n", date, days, newDate);
    }

    // 日期减天数 或 日期差值计算
    private static void flexibleDateCalculation() {
        System.out.println("==== 日期减天数 或 日期减日期差计算 ====");
        LocalDate date1 = inputDate("请输入第一个日期(格式 yyyy-MM-dd)：");
        //用户输入数字 → 返回 Integer
        //用户输入日期 → 返回 LocalDate,多态的使用
        Object input = inputDateOrDays("请输入第二个参数（天数或日期）：");
        //输入整形天数就返回int，进入其中一条if语句，
        // 如果输入的是这个日期，那就返回data日期对象，方法的重载
        //实例化判断方法
        if (input instanceof Integer) {
            //input 的编译时类型是 Object
            //instanceof 是运行时判断,因此在这里必须要进行强转，防止静态编译不通过
            int days = (Integer) input;
            LocalDate newDate = date1.minusDays(days); // 减去天数，返回新日期 ——【日期减法】
            System.out.printf("%s 减去 %d 天后是 %s\n", date1, days, newDate);
        } else {
            LocalDate date2 = (LocalDate) input;
            // 计算两日期间的天数差
            long diff = ChronoUnit.DAYS.between(date2, date1);
            System.out.printf("%s 和 %s 相差 %d 天\n", date1, date2, Math.abs(diff));
        }
    }
}